package org.wu.framework.lazy.orm.database.sql.expand.database.persistence.audit;

import org.wu.framework.lazy.database.datasource.proxy.audit.LazyAuditAdapter;
import org.wu.framework.lazy.database.datasource.proxy.sql.LazySQLContext;
import org.wu.framework.lazy.database.datasource.proxy.toolkit.AuditStatus;
import org.wu.framework.lazy.database.datasource.proxy.toolkit.DynamicLazySQLAuditStatusHolder;
import org.wu.framework.lazy.orm.database.lambda.dynamic.toolkit.DynamicLazyAuditDSContextHolder;
import org.wu.framework.lazy.orm.database.lambda.dynamic.toolkit.DynamicLazyDSContextHolder;
import org.wu.framework.lazy.orm.core.persistence.conf.LazyDynamicEndpoint;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.List;

/**
 * description sql 审计适配器
 *
 * @author 吴佳伟
 * @date 2023/05/13 12:33
 */
public class AuditAdapter implements LazyAuditAdapter {

    private final Logger log = LoggerFactory.getLogger(AuditAdapter.class);

    private final List<Audit> auditList;

    public AuditAdapter(List<Audit> auditList) {
        this.auditList = auditList;
    }

    public void setAuditList(List<Audit> auditList) {
        this.auditList.addAll(auditList);
    }


    /**
     * @param lazySQLContext 执行的sql信息
     */
    @Override
    public void audit(LazySQLContext lazySQLContext) {
        String sql = lazySQLContext.getSql();
        // 获取审计状态
        AuditStatus peek = DynamicLazySQLAuditStatusHolder.peek();
        // 使用原始数据源
        LazyDynamicEndpoint lazyDynamicEndpoint = DynamicLazyDSContextHolder.peek();
        DynamicLazyDSContextHolder.clear();
        if (peek == null || AuditStatus.AUDIT.equals(peek)) {
            DynamicLazyAuditDSContextHolder.push(lazyDynamicEndpoint);
            // 执行sql审计
            auditList.forEach(audit -> {
                // 删除 sql 审计 标识
                DynamicLazySQLAuditStatusHolder.push(AuditStatus.NOT_AUDIT);
                if (audit.supports(lazySQLContext)) {
                    try {
                        audit.audit(lazySQLContext);
                    } catch (Exception e) {
                        e.printStackTrace();
                        throw new RuntimeException("SQL 审计异常" + sql);
                    }
                }
                DynamicLazySQLAuditStatusHolder.clear();
            });
            DynamicLazyAuditDSContextHolder.clear();
        }
        if (null != lazyDynamicEndpoint) {
            DynamicLazyDSContextHolder.push(lazyDynamicEndpoint);
        }
    }
}
